package com.ikingtech.platform.service.system.user.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.approve.api.ApproveFormUserApi;
import com.ikingtech.framework.sdk.approve.model.ApproveFormDepartment;
import com.ikingtech.framework.sdk.approve.model.ApproveFormUser;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.user.api.UserMenuApi;
import com.ikingtech.framework.sdk.user.api.UserRoleApi;
import com.ikingtech.framework.sdk.user.model.UserDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.platform.service.system.user.entity.UserDO;
import com.ikingtech.platform.service.system.user.entity.UserDeptDO;
import com.ikingtech.platform.service.system.user.entity.UserPostDO;
import com.ikingtech.platform.service.system.user.entity.UserRoleDO;
import com.ikingtech.platform.service.system.user.service.repository.*;
import lombok.RequiredArgsConstructor;

import java.util.*;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
public class ApproveFormUserService implements ApproveFormUserApi {

    private final UserRepository repo;

    private final ModelConverter converter;

    private final UserRoleRepository userRoleRepo;
    
    private final UserDeptRepository userDeptRepo;

    private final UserPostRepository userPostRepo;

    private final UserMenuApi userMenuApi;

    private final UserRoleApi userRoleApi;

    @Override
    public List<String> loadRoleIds(List<String> userIds) {
        return this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery().select(UserRoleDO::getRoleId).in(UserRoleDO::getUserId, userIds));
    }

    @Override
    public List<String> loadDepartmentIds(List<String> userIds) {
        return this.userDeptRepo.listObjs(Wrappers.<UserDeptDO>lambdaQuery().select(UserDeptDO::getDeptId).in(UserDeptDO::getUserId, userIds));
    }

    @Override
    public List<String> loadPostIds(List<String> userIds) {
        return this.userPostRepo.listObjs(Wrappers.<UserPostDO>lambdaQuery().select(UserPostDO::getPostId).in(UserPostDO::getUserId, userIds));
    }

    @Override
    public List<String> loadIdByRoleId(String roleId) {
        return this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery().select(UserRoleDO::getUserId).eq(UserRoleDO::getRoleId, roleId));
    }

    @Override
    public List<String> loadIdByRoleIds(List<String> roleIds) {
        return this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery().select(UserRoleDO::getUserId).in(UserRoleDO::getRoleId, roleIds));
    }

    @Override
    public List<String> loadIdByDepartmentId(String deptId) {
        return this.userDeptRepo.listObjs(Wrappers.<UserDeptDO>lambdaQuery().select(UserDeptDO::getUserId).eq(UserDeptDO::getDeptId, deptId));
    }

    @Override
    public List<String> loadIdByDepartmentIds(List<String> deptIds) {
        return this.userDeptRepo.listObjs(Wrappers.<UserDeptDO>lambdaQuery().select(UserDeptDO::getUserId).in(UserDeptDO::getDeptId, deptIds));
    }

    @Override
    public List<String> loadIdByPostId(String postId) {
        return this.userPostRepo.listObjs(Wrappers.<UserPostDO>lambdaQuery().select(UserPostDO::getUserId).eq(UserPostDO::getPostId, postId));
    }

    @Override
    public List<ApproveFormUser> loadByIds(List<String> userIds) {
        if (Tools.Coll.isBlank(userIds)) {
            return Collections.emptyList();
        }
        List<UserDO> entities = this.repo.listByIds(userIds);
        return this.convert(entities);
    }

    @Override
    public List<ApproveFormUser> loadByRoleIds(List<String> roleIds) {
        List<String> userIds = this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery().select(UserRoleDO::getUserId).in(UserRoleDO::getRoleId, roleIds));
        if (Tools.Coll.isBlank(userIds)) {
            return Collections.emptyList();
        }
        List<UserDO> entities = this.repo.listByIds(userIds);
        return this.convert(entities);
    }

    @Override
    public Map<String, ApproveFormUser> mapByIds(List<String> userIds) {
        if (Tools.Coll.isBlank(userIds)) {
            return new HashMap<>();
        }
        List<UserDO> entities = this.repo.listByIds(userIds);
        return Tools.Coll.convertMap(this.convert(entities), ApproveFormUser::getUserId);
    }

    @Override
    public ApproveFormUser loadById(String userId) {
        UserDO entity = this.repo.getById(userId);
        if (null == entity) {
            return null;
        }
        return this.convert(this.converter.modelConvert(entity));
    }

    @Override
    public List<String> loadIdByName(String userName) {
        return this.repo.listObjs(Wrappers.<UserDO>lambdaQuery().select(UserDO::getId).like(UserDO::getName, userName));
    }

    @Override
    public List<ApproveFormUser> loadByMenuCode(String menuCode) {
        // 根据菜单编码列表获取菜单id列表
        String menuId = this.userMenuApi.loadIdByCode(menuCode, Me.tenantCode());
        // 根据菜单id列表获取角色id列表
        List<String> roleIds = this.userRoleApi.loadIdByMenuId(menuId, Me.tenantCode());
        // 根据角色id列表查询用户基本信息列表
        if (Tools.Coll.isBlank(roleIds)) {
            return new ArrayList<>();
        }
        // 获取用户id列表
        List<String> userIds = this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery()
                .select(UserRoleDO::getUserId)
                .in(UserRoleDO::getRoleId, roleIds));
        if (Tools.Coll.isBlank(userIds)) {
            return new ArrayList<>();
        }
        return this.convert(this.repo.listByIds(userIds));
    }

    private List<ApproveFormUser> convert(List<UserDO> entities) {
        return Tools.Coll.convertList(this.converter.modelBatchConvert(entities), this::convert);
    }

    private ApproveFormUser convert(UserDTO user) {
        ApproveFormUser approveFormUser = new ApproveFormUser();
        approveFormUser.setUserId(user.getId());
        approveFormUser.setUserName(user.getName());
        approveFormUser.setUserAvatar(user.getAvatar());
        approveFormUser.setUserDeptIds(user.getDeptIds());
        approveFormUser.setUserDepartments(Tools.Coll.convertList(user.getDepartments(), department -> {
            ApproveFormDepartment approveFormDepartment = new ApproveFormDepartment();
            approveFormDepartment.setDeptId(department.getDeptId());
            approveFormDepartment.setDeptName(department.getDeptName());
            approveFormDepartment.setDeptManagerId(department.getManagerId());
            approveFormDepartment.setDeptManagerName(department.getManagerName());
            approveFormDepartment.setDeptManagerAvatar(department.getManagerAvatar());
            return approveFormDepartment;
        }));
        approveFormUser.setUserPostIds(user.getPostIds());
        approveFormUser.setUserRoleIds(user.getRoleIds());
        return approveFormUser;
    }
}
